#!/usr/bin/python3

# from construct import Struct, Const, Byte, Bytes, Int8ub, Computed, Stream
from construct import Struct, Const, Byte, Bytes, Int8ub, Int16ub, Computed, Pointer
# from construct.core import Stream
import struct
import numpy as np

# 定义数据帧的结构
frame_struct = Struct(
    "start" / Const(bytes([0xff,0xee])),       # 开头为 0xff, 0xee
    "length" / Int16ub,                        # 第三个字节表示整个帧长度
    "data" / Bytes(lambda this: this.length),  # 数据部分，长度为 length
    "end" / Const(b"\xee\xff")                 # 结尾为 0xee, 0xff
)


def parse_frame(data, do_action=None):
    tlen = 0
    print(f'tlen:{tlen} {len(data)}')
    print(data[0], data[1], data[2:4])
    try:
        while tlen < len(data):
            frame = frame_struct.parse(data[tlen:])
            do_action(frame.data)
            tlen += len(frame.data) + 6
        return (0, b'')
        
    except Exception as e:
        print("\033[91mReceived an invalid frame:\033[0m", e, tlen)
        return (0, b'')



MyType = np.dtype({
    'names': ['cmd', 'data'],
    'formats': ['S1',  'S255']
})

'''
channel
'''
D = None
C = None
K = None
def print_protocal(data):
    c = np.array(data, dtype=MyType)
    cmd = c['cmd'].tolist()
    data = c['data'].tolist()
    global D
    global C ,K
    K = c
    C = c['cmd'].tolist()
    D = c['data'].tolist()

    np.savetxt("/tmp/a.csv", c, delimiter=',')
    # cmd = list(c['cmd'])
    # data = list(c['data'])
    print("cmd", list(cmd), "data",  list(data))
    # print('%x', {k})
    print("this is c", c['cmd'], c['data'])
    

'''
构造数据帧
data_frame = bytes([
    0xff, 0xee, 
    0x00,0x0a,
    0x01,0x02,0x03,0x04,0x05,0x6,0x7,0x8,0x9,0xa,
    0xee,0xff])
'''
def build_adframe(data):
    frame = bytes([0xff, 0xee]) + \
            (len(data)).to_bytes(2, byteorder='big') + \
            data + \
            bytes([0xee,0xff])
    return frame
if __name__ == "__main__":

    # 示例数据帧
    data_frame = build_adframe(b"\x01bc") + \
                build_adframe(b"\xffdef") + \
                build_adframe(b"abcdefg") 
                # + \
                # build_adframe(bytes([0x22, 0x11, 0x01,0x02,0x03,0x04,0x05,0x6,0x7,0x8,0x9,0xa]))
    # data_frame =   build_adframe(bytes([0x32, 0x01,0x02,0x03,0x04,0x05,0x6,0x7,0x8,0x9,0xa]))
    # 解析数据帧

    flen, d = parse_frame(data_frame, print_protocal)
    print("recognise", flen, d)
    # exit(0)

    import socket

    # 创建 UDP 套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定 IP 地址和端口
    udp_socket.bind(('127.0.0.1', 9999))

    print("UDP 服务器启动，等待客户端消息...")

    while True:
        # 接收数据
        data, addr = udp_socket.recvfrom(1024)
        print(type(data))
        flen, d = parse_frame(data, print_protocal)
        # print(f"接收到来自 {addr} 的消息: {data.decode()}")
        # print(f"接收到来自 {addr} 的消息: {data}")
    # 关闭套接字
    udp_socket.close()
